﻿namespace Sustainalytics.Portfolios.Servive.Tests
{
    using System;
    using System.Net;
    using System.Net.Http;
    using System.Threading.Tasks;
    using System.Web;
    using System.Web.Http;
    using System.Web.Http.Dispatcher;

    using FakeItEasy;

    using Microsoft.Owin.Testing;

    using Owin;

    using Sustainalytics.Claims;
    using Sustainalytics.Portfolios.Service;
    using Sustainalytics.Portfolios.Service.Infrastructure;
    using Sustainalytics.Portfolios.Service.Utility;

    using Xunit;

    public partial class PortfolioServiceTests
    {
        private readonly Uri _uri = new Uri("http://testserver/api/v1/portfolios/");

        private void CreateConfiguration(IAppBuilder appBuilder, bool isAuthorized = true)
        {
            using (var config = new HttpConfiguration())
            {
                appBuilder.Use<OwinExceptionMiddleware>();
                config.Services.Replace(typeof(IHttpControllerActivator), new TestCompositionRoot());

                config.Routes.MapHttpRoute(
                    name: "ApiById",
                    routeTemplate: "api/{controller}/{id}",
                    defaults: new { id = RouteParameter.Optional },
                    constraints: new { id = @"^[0-9]+$" });
                WebApiConfig.Register(config);
                config.Filters.Add(new CustomExceptionFilter());
                var fakeClaimsChecker = A.Fake<IClaimsChecker>();
                PortfolioClaimsCheckerExtensions.ApiControllerValidator = (checker, controller, arg3) => isAuthorized;
                config.Filters.Add(new ClaimFilter(fakeClaimsChecker));
                config.Formatters.XmlFormatter.SupportedMediaTypes.Clear();
                appBuilder.UseWebApi(config);
                config.EnsureInitialized();
            }
        }

        [Fact]
        public async Task When_Name_Null_Response_Is_Unsuccessful()
        {
            using (TestServer server = TestServer.Create(app => this.CreateConfiguration(app)))
            {
                var httpclient = new HttpClient(server.Handler);

                var builder = this.BuildUri(string.Empty);
                var request = new HttpRequestMessage(new HttpMethod("PATCH"), builder.ToString());

                HttpResponseMessage response = await httpclient.SendAsync(request).ConfigureAwait(false);
                Assert.False(response.IsSuccessStatusCode);
            }
        }

        [Fact]
        public async Task When_RenameHandler_Throws_ModificationUnauthorized_Response_is_forbidden()
        {
            using (TestServer server = TestServer.Create(app => this.CreateConfiguration(app)))
            {
                var httpclient = new HttpClient(server.Handler);

                var builder = this.BuildUri("test1");
                var request = new HttpRequestMessage(new HttpMethod("PATCH"), builder.ToString());

                HttpResponseMessage response = await httpclient.SendAsync(request).ConfigureAwait(false);
                Assert.Equal(HttpStatusCode.Forbidden, response.StatusCode);
            }
        }

        private UriBuilder BuildUri(string name)
        {
            var builder = new UriBuilder(this._uri);
            var query = HttpUtility.ParseQueryString(builder.Query);
            query["id"] = "98A0EA1C-F785-48D4-A2FB-B50088586F8A";
            query["newName"] = name;
            builder.Query = query.ToString();
            return builder;
        }
    }
}